/*
 * File: DataUtil.java
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package tvseries.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

import org.apache.log4j.Logger;
import org.hibernate.ObjectNotFoundException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import tvseries.entity.Episode;
import tvseries.entity.Series;
import tvseries.imdb.DataHarvester;

/**
 * Utility class for basic database interactions. Currently need to create more complex local code for doing
 * extended transactions.
 * 
 * @author nish.naidoo@gmail.com
 * 
 */
public class DataUtil
{
	private static final Logger log = Logger.getLogger(DataUtil.class);

	private static DataHarvester harvester = null;

	static
	{
		harvester = new DataHarvester();
	}

	public static Episode getEpisode(String id)
	{
		Episode e = (Episode) HibernateUtil.load(Episode.class, id);
		return e;
	}

	public static void saveEpisode(Episode e)
	{
		HibernateUtil.persist(e);
	}

	public static void loadSeriesListing()
	{
		File shows = new File(PropUtil.get("series.listing"));
		Scanner scanner = null;
		try
		{
			scanner = new Scanner(shows);
		}
		catch (FileNotFoundException fnfe)
		{
			log.fatal("File not found: " + PropUtil.get("series.listing"), fnfe);
		}

		while (scanner.hasNextLine())
		{
			String line = scanner.nextLine();
			String[] parts = line.split(" *\t *");
			String id = parts[0];
			String title = parts[1];
			if (log.isDebugEnabled())
				log.debug("Obtained [ " + id + ": " + title + " ]");

			Series series = null;
			try
			{
				series = (Series) HibernateUtil.load(Series.class, id);
			}
			catch (ObjectNotFoundException onfe)
			{
				if (log.isDebugEnabled())
					log.debug("Creating new series:" + id);

				series = new Series();
				series.setId(id);
				series.setTitle(title);
				series.setImdbUrl(PropUtil.get("imdb.url.base") + id);
			}

			HibernateUtil.persist(series);
		}
	}

	public static void updateSeries(String seriesId) throws Exception
	{
		Series series = (Series) HibernateUtil.load(Series.class, seriesId);
		if (log.isDebugEnabled())
			log.debug("[" + series.getId() + "] Title: " + series.getTitle());

		Set<Episode> episodes = harvester.getEpisodeData(series);
		for (Episode e : episodes)
		{
			Episode tmp = getEpisode(series, e.getId());
			if (tmp != null)
			{			
				String status = tmp.getStatus(); 
				if (status != null && (status.equals("Ignored") || status.equals("Archived")))
				{
					e.setStatus(tmp.getStatus());
				}
			}
			
			e.setSeries(series);
			HibernateUtil.persist(e);
		}

		Series tmp = harvester.getSeriesData(series.getId(), series.getTitle());

		series.setEpisodes(episodes);
		series.setLastUpdate(new Date());
		series.setSummary(tmp.getSummary());

		HibernateUtil.persist(series);
	}

	public static List<Series> getSeries()
	{
		@SuppressWarnings("unchecked")
		List<Series> series = (List<Series>) HibernateUtil.getObjects(Series.class);

		return series;
	}
	
	@SuppressWarnings("unchecked")
	public static List<Episode> getMissingEpisodes()
	{
		List<Episode> episodes = null;
		
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction tx = session.beginTransaction();
		episodes = session.createQuery("from Episode as e where e.status = ? order by e.series.title, e.season, e.episode")
						  .setString(0, "Missing")
						  .list();
		tx.commit();

		return episodes;
	}
	
	public static void deleteSeries(String id)
	{
		try
		{
			Series series = (Series) HibernateUtil.load(Series.class, id);
			HibernateUtil.delete(series);
		}
		catch (ObjectNotFoundException onfe)
		{
			log.warn("Object you are trying to delete does not exist: " + id);
		}
	}

	private static Episode getEpisode(Series series, String id)
	{
		for (Episode e : series.getEpisodes())
			if (e.getId().equals(id))
				return e;

		return null;
	}
}
